package com.ng.desktop.view.dieta;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;

import org.apache.commons.lang.StringUtils;

import com.ng.framework.view.desktop.table.NGCustomTable;

public class ParametrosInicialesPanel extends JPanel {

	private static final long serialVersionUID = 6731236636420395200L;

	private static final int FILA_CHON = 0;
	private static final int FILA_CHO = 1;
	private static final int FILA_FAT = 2;
	private static final int FILA_TOTAL = 3;

	private static final int COL_NUTRIENTE = 0;
	private static final int COL_GRAMOS = 1;
	private static final int COL_CALORIAS = 2;
	private static final int COL_PROPORCION = 3;

	private static final int COEFICIENTE_CHON_CHO = 4;
	private static final int COEFICINETE_FAT = 9;

	private static final Color RED = new Color(250, 128, 114);
	private static final Color YELLOW = new Color(255, 215, 0);
	private static final Color GREEN = new Color(141, 188, 143);
	private static final Color BLUE = new Color(70, 130, 180);

	private JTextField nombreTextField;
	private JTextField apellidoTextField;
	private JTextField dietaSugeridaTextField;
	private JTextField duracionDietaTextField;
	private NGCustomTable tableDistribucion;

	private JButton buttonSiguiente;

	public ParametrosInicialesPanel(JButton buttonSiguiente) {
		this.buttonSiguiente = buttonSiguiente;

		this.buildGui();
	}

	private void buildGui() {
		this.setLayout(new GridBagLayout());

		this.add(new JLabel("Nombre:"), new GridBagConstraints(0, 0, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		this.add(this.getNombreTextField(), new GridBagConstraints(1, 0, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		this.add(new JLabel("Apellido:"), new GridBagConstraints(0, 1, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		this.add(this.getApellidoTextField(), new GridBagConstraints(1, 1, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0));
		this.add(new JLabel("Dieta sugerida:"), new GridBagConstraints(0, 2, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		this.add(this.getDietaSugueridaTextField(), new GridBagConstraints(1, 2, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));
		this.add(new JLabel("Duración:"), new GridBagConstraints(0, 3, 1, 1, 0, 0, GridBagConstraints.EAST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0));
		this.add(this.getDuracionDietaTextField(), new GridBagConstraints(1, 3, 1, 1, 1, 0, GridBagConstraints.WEST,
				GridBagConstraints.NONE, new Insets(0, 0, 5, 0), 0, 0));

		JScrollPane scrollPane = new JScrollPane(this.getTableDistribucion(), JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		scrollPane.setBorder(BorderFactory.createTitledBorder("Distribución calórica"));
		this.add(scrollPane, new GridBagConstraints(0, 4, 2, 1, 1, 1, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
				new Insets(0, 0, 0, 0), 0, 0));

	}

	private JTextField getNombreTextField() {
		if (nombreTextField == null) {
			this.nombreTextField = new JFormattedTextField();
			this.nombreTextField.getDocument().addDocumentListener(new DocumentListener() {

				@Override
				public void removeUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void insertUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void changedUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}
			});
		}
		return nombreTextField;
	}

	private JTextField getApellidoTextField() {
		if (apellidoTextField == null) {
			this.apellidoTextField = new JFormattedTextField();
			this.apellidoTextField.getDocument().addDocumentListener(new DocumentListener() {

				@Override
				public void removeUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void insertUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void changedUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}
			});
		}
		return apellidoTextField;
	}

	private JTextField getDietaSugueridaTextField() {
		if (dietaSugeridaTextField == null) {
			this.dietaSugeridaTextField = new JTextField(4);
			dietaSugeridaTextField.setMinimumSize(dietaSugeridaTextField.getPreferredSize());
			dietaSugeridaTextField.setHorizontalAlignment(JTextField.RIGHT);
			dietaSugeridaTextField.getDocument().addDocumentListener(new DocumentListener() {

				@Override
				public void removeUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.updateTable();
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void insertUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.updateTable();
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void changedUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.updateTable();
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}
			});
		}
		return dietaSugeridaTextField;
	}

	public void updateTable() {
		Integer dietaSugerida;
		try {
			dietaSugerida = Integer.parseInt(this.getDietaSugueridaTextField().getText());
		} catch (NumberFormatException e) {
			dietaSugerida = 0;
		}

		Double totalCalorias = 0d;
		Double totalProporcion = 0d;

		for (int i = 0; i < this.getTableDistribucion().getRowCount() - 1; i++) {
			Double proporcion = (Double) this.getTableDistribucion().getValueAt(i, COL_PROPORCION);
			if (proporcion == null) {
				proporcion = 0d;
			}
			totalProporcion += proporcion;

			Double calorias = dietaSugerida * proporcion;
			this.getTableDistribucion().setValueAt(calorias, i, COL_CALORIAS);
			totalCalorias += calorias;

			Double gramos = calorias / (i == FILA_FAT ? COEFICINETE_FAT : COEFICIENTE_CHON_CHO);
			this.getTableDistribucion().setValueAt(gramos, i, COL_GRAMOS);
		}

		this.getTableDistribucion().setValueAt(totalCalorias, FILA_TOTAL, COL_CALORIAS);
		this.getTableDistribucion().setValueAt(totalProporcion, FILA_TOTAL, COL_PROPORCION);

		Color foregroundCalorias;
		if (totalCalorias < dietaSugerida) {
			foregroundCalorias = YELLOW;
		} else if (totalCalorias > dietaSugerida) {
			foregroundCalorias = RED;
		} else {
			foregroundCalorias = GREEN;
		}

		this.getTableDistribucion().setCellForeground(FILA_TOTAL, COL_CALORIAS, foregroundCalorias);

		Color foregroundProporcion;
		if (totalProporcion < 1) {
			foregroundProporcion = YELLOW;
		} else if (totalProporcion > 1) {
			foregroundProporcion = RED;
		} else {
			foregroundProporcion = GREEN;
		}
		
		//Activamos la validacion de siguiente
		this.enableButtonSiguiente();

		this.getTableDistribucion().setCellForeground(FILA_TOTAL, COL_PROPORCION, foregroundProporcion);
	}

	private JTextField getDuracionDietaTextField() {
		if (duracionDietaTextField == null) {
			this.duracionDietaTextField = new JTextField(2);
			duracionDietaTextField.setMinimumSize(duracionDietaTextField.getPreferredSize());
			duracionDietaTextField.setHorizontalAlignment(JTextField.RIGHT);
			duracionDietaTextField.getDocument().addDocumentListener(new DocumentListener() {

				@Override
				public void removeUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void insertUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}

				@Override
				public void changedUpdate(DocumentEvent e) {
					ParametrosInicialesPanel.this.enableButtonSiguiente();
				}
			});

		}
		return duracionDietaTextField;
	}

	private void enableButtonSiguiente() {
		boolean enabled = true;
		if (!StringUtils.isBlank(this.getNombreTextField().getText())
				&& !StringUtils.isBlank(this.getApellidoTextField().getText()) && tableDistribucion.getValueAt(3, 3).equals(1d)) {
			try {
				Integer.parseInt(this.getDietaSugueridaTextField().getText().trim());
				Integer.parseInt(this.getDuracionDietaTextField().getText().trim());
			} catch (NumberFormatException e) {
				enabled = false;
			}
		} else {
			enabled = false;
		}
		buttonSiguiente.setEnabled(enabled);
	}

	private NGCustomTable getTableDistribucion() {
		if (tableDistribucion == null) {
			tableDistribucion = new NGCustomTable(new Object[]{"Nutriente", "Gramos", "Calorías", "Proporción (%)"});

			tableDistribucion.getModel().addTableModelListener(new TableModelListener() {

				@Override
				public void tableChanged(TableModelEvent e) {
					if (e.getColumn() == COL_PROPORCION && e.getFirstRow() >= 0 && e.getFirstRow() < FILA_TOTAL) {
						ParametrosInicialesPanel.this.updateTable();
					}
				}
			});

			tableDistribucion.addRow(new Object[]{"CHON", 0d, 0d, 0.18d});
			tableDistribucion.addRow(new Object[]{"CHO", 0d, 0d, 0.6d});
			tableDistribucion.addRow(new Object[]{"FAT", 0d, 0d, 0.22d});
			tableDistribucion.addRow(new Object[]{"Total", null, 0, 1d});

			tableDistribucion.setNumericColumn(COL_PROPORCION, Double.class);

			tableDistribucion.setCellEditable(FILA_CHON, COL_PROPORCION, true);
			tableDistribucion.setCellForeground(FILA_CHON, COL_PROPORCION, BLUE);
			tableDistribucion.setCellEditable(FILA_CHO, COL_PROPORCION, true);
			tableDistribucion.setCellForeground(FILA_CHO, COL_PROPORCION, BLUE);
			tableDistribucion.setCellEditable(FILA_FAT, COL_PROPORCION, true);
			tableDistribucion.setCellForeground(FILA_FAT, COL_PROPORCION, BLUE);

			tableDistribucion.combine(FILA_TOTAL, COL_NUTRIENTE, 1, 2);

			tableDistribucion.setCellAlignment(FILA_TOTAL, COL_NUTRIENTE, SwingUtilities.RIGHT);
		}
		return tableDistribucion;
	}

	public Double getChon() {
		return (Double) this.getTableDistribucion().getValueAt(FILA_CHON, COL_GRAMOS);
	}

	public Double getCho() {
		return (Double) this.getTableDistribucion().getValueAt(FILA_CHO, COL_GRAMOS);
	}

	public Double getFat() {
		return (Double) this.getTableDistribucion().getValueAt(FILA_FAT, COL_GRAMOS);
	}

	public Double getEnergia() {
		return (Double) this.getTableDistribucion().getValueAt(FILA_TOTAL, COL_CALORIAS);
	}

	public Integer getDuracion() {
		return Integer.parseInt(this.getDuracionDietaTextField().getText());
	}

	public String getPaciente() {
		return this.getApellidoTextField().getText() + ", " + this.getNombreTextField().getText();
	}

	public Integer getCalorias() {
		return Integer.parseInt(this.getDietaSugueridaTextField().getText());
	}
}
